#include "setup.h"

/**
 * Does the installation ofthe TIMER0 interrupts
 */
void timer_setup()
{	
	timer_load(0, (int)(TIMER_CLK));
	install_asm_irq_handler(T0_IRQ, program, &old_timer_irq); // installs the custom handler for the timer interrupts
}

/**
 * Does the installation of the mouse and keyboard interrupts
 */
void kbd_and_mouse_init()
{
	// initialization of the mouse and keyboard queues
	mouse_queue = newGQueue(10, sizeof(MouseData)); 
	apontQueue = &keysQueue;
	queueInit(apontQueue);
				
	disable_irq(KBD_IRQ); //disable keyboard interrupts
	disable_irq(MOUSE_IRQ); //disable mouse interrupts
		
	if (kbc_init(0) != 1)
			exit(0);
		
	install_asm_irq_handler(KBD_IRQ, handler, &old_kbd_irq); //install the keyboard handler
	install_asm_irq_handler(MOUSE_IRQ, mouse_handler, &old_mouse_irq); //install the mouse handler
	
	enable_irq(MOUSE_IRQ);//enable mouse interrupts
	enable_irq(KBD_IRQ); //enable keyboard interrupts
}

/**
 * Does the installation of the RTC interrupts
  */
void rtc_setup()
{
	install_c_irq_handler(RTC_IRQ, rtc_isr, &old_rtc); // installs the custom handler for the rtc interrupts
	disable_irq(RTC_IRQ);
	outportb(RTC_ADDR_REG,RTC_STAT_B);
	outportb(RTC_DATA_REG, inportb(RTC_DATA_REG) | RTC_PIE | RTC_AIE | RTC_UIE); // enables the periodics, alarm and update interrupts in the rtc
	enable_irq(RTC_IRQ);	
}

/**
 * Handler to rtc interrupts
 */
void rtc_isr() 
{
	//stores the type of interrupt that is occuring
	Byte tipo = read_rtcv(RTC_STAT_C);
	
	// sets the RTC_EVENT bit in the variable event
	if(tipo & RTC_PF) {	
		event |= RTC_EVENT;
	}
	
	if(tipo & RTC_AF) {
	}
	//the time of the level is decreased when an update interrupt occurs
	if(tipo & RTC_UF) {
		if(!pause) 
			level.seconds--; 
	}
	
	outportb(PIC1_CMD, EOI); // end of interrupt
	outportb(PIC2_CMD, EOI); // end of interrupt
}

/**
 * Does the installation of all the interrupts and initializes the game variables
 */
void init()
{
	//graphic mode enabled
	base = enter_graphics(mode, &mem_map);
	//installs timer interrupts
	timer_setup();
	//installs rtc interrupts
	rtc_setup();
	//installs keyboard and mouse interrupts
	kbd_and_mouse_init();
	
	//initializes game variables
	level.level = 1;
	score = 0;
	bestScore = 0;
	fire_active = false;
	game_on = false;
	help = false;
	pause = false;
	
	load_char_table(table);
}

/**
 * Reinstalls the keyboard and mouse interrupts
  */
void kbd_and_mouse_finish()
{
	disable_irq(KBD_IRQ); //disable keyboard interrupts
	disable_irq(MOUSE_IRQ); //disable mouse interrupts
	
	reinstall_asm_irq_handler(MOUSE_IRQ, &old_mouse_irq);
	reinstall_asm_irq_handler(KBD_IRQ, &old_kbd_irq);
	
	enable_irq(MOUSE_IRQ);//enable mouse interrupts
	enable_irq(KBD_IRQ); //enable keyboard interrupts
}


/**
 * Reinstalls the rtc interrupts
  */
void rtc_finish()
{
	disable_irq(RTC_IRQ);
	write_rtcv(RTC_STAT_B, read_rtcv(RTC_STAT_B) & ~(RTC_PIE | RTC_AIE | RTC_UIE));
	//reinstall_c_irq_handler(RTC_IRQ, &old_rtc);
}

/**
 * Reinstalls the TIMER0 interrupts
  */
void timer_finish()
{
	// reinstalls the original timer interrupts handler
	reinstall_asm_irq_handler(T0_IRQ, &old_timer_irq);
}

/**
 * reinstall all the interrupts that where installed before
 */
void finalize()
{
	//leaving graphic mode
	leave_graphics(mem_map);
	//reinstall the keyboard and the mouse original interrupts
	kbd_and_mouse_finish();
	//reinstall the rtc original interrupts
	rtc_finish();
	//reinstall the timer original interrupts
	timer_finish();
}
